/**
 ******************************************************************************
 * @file     xmc_ecc.h
 * @version  v2.0.3
 * @date     2021-12-17
 * @brief    header file for the nand ecc configuration.
 ******************************************************************************
 *                       Copyright notice & Disclaimer
 *
 * The software Board Support Package (BSP) that is made available to
 * download from Artery official website is the copyrighted work of Artery.
 * Artery authorizes customers to use, copy, and distribute the BSP
 * software and its related documentation for the purpose of design and
 * development in conjunction with Artery microcontrollers. Use of the
 * software is governed by this copyright notice and the following disclaimer.
 *
 * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
 * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
 * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
 * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
 * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
 *
 **************************************************************************
 */

#ifndef __XMC_NAND_ECC_H
#define __XMC_NAND_ECC_H

#include "stdint.h"
#include "framework.h"

#ifdef __cplusplus
extern "C"
{
#endif

/** @addtogroup AT32F437_periph_examples
 * @{
 */

/** @addtogroup 437_XMC_nand_ecc
 * @{
 */
#define K9GAG08U0E

	/** @defgroup NAND_id_define
	 * @{
	 */

	typedef union
	{
		uint32_t id;
		struct
		{
			uint8_t device_id; /*!< device id */
			uint8_t third_id;  /*!< third id */
			uint8_t fourth_id; /*!< fourth id */
			uint8_t fifth_id;  /*!< fifth id */
			uint8_t sixth_id;  /*!< sixth id */
			uint8_t maker_id;  /*!< maker id */
		};
	} nand_id_type;

	/**
	 * @}
	 */

	/** @defgroup NAND_address_define
	 * @{
	 */

	typedef struct
	{
		uint16_t block; /*!< nand device block address */
		uint16_t page;	/*!< nand device page address */
		uint16_t byte;	/*!< nand device byte address */
	} nand_address_type;

	/**
	 * @}
	 */

	// NAND属性结构体
	typedef struct
	{
		u32 id;				// NAND FLASH ID
		u16 page_totalsize; // 每页总大小，main区和spare区总和
		u16 page_mainsize;	// 每页的main区大小
		u16 page_sparesize; // 每页的spare区大小
		u8 block_pagenum;	// 每个块包含的页数量
		u16 plane_blocknum; // 每个plane包含的块数量
		u16 block_totalnum; // 总的块数量
		u8 ecc_err_st;		// ECC 错误状态，无法修复的个数，执行page_read后获取
		u8 ecc_cok_st;		// ECC 修改状态，修复成功的个数，执行page_read后获取
		u32 ecc_hdbuf[8];	// ECC硬件计算值缓冲区
		u32 ecc_rdbuf[8];	// ECC读取的值缓冲区
	} nand_attriute;

	extern nand_attriute atio_nand;

#define ROW_ADDRESS page
#define COL_ADDRESS coil

#define BUFFER_SIZE NAND_PAGE_SIZE

#define XMC_Bank_NAND XMC_Bank2_NAND
#define Bank_NAND_ADDR Bank2_NAND_ADDR
#define Bank2_NAND_ADDR ((uint32_t)0x70000000)

#ifdef H27U1G8F2CTR_
#define NAND_AT_MakerID 0xAD
#define NAND_AT_DeviceID 0xF1
#elif defined K9GAG08U0E_
#define NAND_AT_MakerID 0xEC
#define NAND_AT_DeviceID 0xD5
#endif

/** @defgroup NAND_area_define
 * @{
 */

/* a16 = cle  high */
#define CMD_AREA (uint32_t)(1 << 16)
/* a17 = ale  high */
#define ADDR_AREA (uint32_t)(1 << 17)

#define DATA_AREA ((uint32_t)0x00000000)

/**
 * @}
 */

/** @defgroup XMC_nand_memory_command
 * @{
 */

/*-- XMC NAND memory command -------------------------------------*/
#define NAND_CMD_AREA_A ((uint8_t)0x00)
#define NAND_CMD_AREA_B ((uint8_t)0x01)
#define NAND_CMD_AREA_C ((uint8_t)0x50)
#define NAND_CMD_AREA_TRUE1 ((uint8_t)0x30)

#define NAND_CMD_WRITE0 ((uint8_t)0x80)
#define NAND_CMD_WRITE_TRUE1 ((uint8_t)0x10)

#define NAND_CMD_ERASE0 ((uint8_t)0x60)
#define NAND_CMD_ERASE1 ((uint8_t)0xD0)

#define NAND_CMD_READID ((uint8_t)0x90)
#define NAND_CMD_STATUS ((uint8_t)0x70)
#define NAND_CMD_LOCK_STATUS ((uint8_t)0x7A)
#define NAND_CMD_RESET ((uint8_t)0xFF)

/**
 * @}
 */

/** @defgroup XMC_nand_status
 * @{
 */

/*-- nand memory status -------------------------------------*/
#define NAND_VALID_ADDRESS ((uint32_t)0x00000100)
#define NAND_INVALID_ADDRESS ((uint32_t)0x00000200)
#define NAND_TIMEOUT_ERROR ((uint32_t)0x00000400)
#define NAND_BUSY ((uint32_t)0x00000000)
#define NAND_ERROR ((uint32_t)0x00000001)
#define NAND_READY ((uint32_t)0x00000040)

/**
 * @}
 */

// NAND FLASH型号和对应的ID号
#define MT29F1G08ABADA 0XF1809502  // MT29F1G08ABADA
#define MT29F4G08ABADA 0XDC909556  // MT29F4G08ABADA
#define MT29F16G08ABABA 0X48002689 // MT29F16G08ABABA

/** @defgroup XMC_nand_parameters
 * @{
 */

/**
 * @}
 */

/** @defgroup XMC_nand_address_computation
 * @{
 */

/*-- xmc nand memory address computation -------------------------------------*/
/* 1st addressing cycle */
#define addr_1st_cycle(addr) (uint8_t)((addr)&0xFF)
/* 2nd addressing cycle */
#define addr_2nd_cycle(addr) (uint8_t)(((addr)&0xFF00) >> 8)
/* 3rd addressing cycle */
#define addr_3rd_cycle(addr) (uint8_t)(((addr)&0xFF0000) >> 16)
/* 4th addressing cycle */
#define addr_4th_cycle(addr) (uint8_t)(((addr)&0xFF000000) >> 24)

	/**
	 * @}
	 */

	/** @defgroup XMC_nand_ecc_functions
	 * @{
	 */

	void nand_init(void);
	uint32_t nand_read_id(nand_id_type *nand_id_struct);
	uint32_t nand_write_page(uint8_t *pbuffer, uint32_t page, uint32_t coil, uint16_t len);
	uint32_t nand_read_page(uint8_t *pbuffer, uint32_t page, uint32_t coil, uint16_t len);
	uint32_t nand_write_spare_area(uint8_t *pbuffer, uint32_t page, uint32_t coil, uint16_t len);
	uint32_t nand_read_spare_area(uint8_t *pbuffer, uint32_t page, uint32_t coil, uint16_t len);
	uint32_t nand_erase_block(uint16_t block);
	uint32_t nand_reset(void);
	uint32_t nand_get_status(void);
	uint32_t nand_read_status(void);
	uint8_t nand_ecc_correction(uint8_t *pbuffer, uint32_t tx_ecc_value, uint32_t rx_ecc_value);

/**
 * @}
 */

/**
 * @}
 */

/**
 * @}
 */
#ifdef __cplusplus
}
#endif

#endif
